package com.zhentao.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhentao.pojo.User;
import com.zhentao.websocket.pojo.ChatMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChatMessageService {

    private static final Logger log = LoggerFactory.getLogger(ChatMessageService.class);

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserService userService;

    /**
     * 保存聊天消息
     */
    public ChatMessage saveMessage(ChatMessage message) {
        try {
            // 验证消息内容
            if (message == null) {
                throw new IllegalArgumentException("消息不能为空");
            }
            
            if (message.getFromName() == null || message.getFromName().trim().isEmpty()) {
                throw new IllegalArgumentException("发送者不能为空");
            }
            
            if (message.getToName() == null || message.getToName().trim().isEmpty()) {
                throw new IllegalArgumentException("接收者不能为空");
            }
            
            if (message.getMessage() == null || message.getMessage().trim().isEmpty()) {
                throw new IllegalArgumentException("消息内容不能为空");
            }
            
            // 清理和标准化数据
            message.setFromName(message.getFromName().trim());
            message.setToName(message.getToName().trim());
            message.setMessage(message.getMessage().trim());
            
            // 设置默认值
            if (message.getTimestamp() == null) {
                message.setTimestamp(LocalDateTime.now());
            }
            
            if (message.getMessageType() == null || message.getMessageType().trim().isEmpty()) {
                message.setMessageType("text");
            }
            
            // 生成会话ID (用于快速查询对话)
            message.setConversationId(generateConversationId(message.getFromId().toString(), message.getToId().toString()));

            // 获取并设置双方头像信息
            setUserAvatars(message);
            System.out.println("server 层数据"+ message);

            // 保存到MongoDB
            ChatMessage saved = mongoTemplate.save(message);
            log.info("消息保存成功: {} -> {}, ID: {}, 会话ID: {}", 
                message.getFromName(), message.getToName(), saved.getId(), saved.getConversationId());
            
            return saved;
        } catch (Exception e) {
            log.error("保存消息失败: {}", message != null ? message.toString() : "null", e);
            throw new RuntimeException("保存消息失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 批量保存消息
     */
    public List<ChatMessage> saveMessages(List<ChatMessage> messages) {
        try {
            if (messages == null || messages.isEmpty()) {
                return new ArrayList<>();
            }
            
            // 验证所有消息
            for (ChatMessage message : messages) {
                if (message.getFromName() == null || message.getToName() == null || message.getMessage() == null) {
                    throw new IllegalArgumentException("批量保存中包含无效消息");
                }
                
                // 设置默认值
                if (message.getTimestamp() == null) {
                    message.setTimestamp(LocalDateTime.now());
                }
                if (message.getMessageType() == null) {
                    message.setMessageType("text");
                }
                message.setConversationId(generateConversationId(message.getFromId().toString(), message.getToId().toString()));
            }
            
            Collection<ChatMessage> saved = mongoTemplate.insertAll(messages);
            List<ChatMessage> result = new ArrayList<>(saved);
            log.info("批量保存消息成功，数量: {}", result.size());
            return result;
            
        } catch (Exception e) {
            log.error("批量保存消息失败", e);
            throw new RuntimeException("批量保存消息失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 生成会话ID（两个用户之间的唯一标识）
     */
    private String generateConversationId(String user1, String user2) {
        // 按字典序排列，确保同一对用户生成相同的会话ID
        String[] users = {user1, user2};
        Arrays.sort(users);
        return users[0] + "_" + users[1];
    }

    /**
     * 获取两个用户之间的聊天记录（优化版）
     */
    public List<ChatMessage> getChatHistory(String user1, String user2, int page, int size) {
        try {
            if (user1 == null || user2 == null || user1.trim().isEmpty() || user2.trim().isEmpty()) {
                throw new IllegalArgumentException("用户名不能为空");
            }

            user1 = user1.trim();
            user2 = user2.trim();

            Query query = new Query();

            // 使用conversationId优化查询性能
            String conversationId = generateConversationId(user1, user2);
            Criteria criteria = Criteria.where("conversationId").is(conversationId)
                    .and("isDeleted").is(false);

            query.addCriteria(criteria);

            // 按时间倒序排列
            query.with(Sort.by(Sort.Direction.DESC, "timestamp"));

            // 分页
            if (page >= 0 && size > 0) {
                Pageable pageable = PageRequest.of(page, size);
                query.with(pageable);
            }

            List<ChatMessage> messages = mongoTemplate.find(query, ChatMessage.class);

            // 反转列表，使最新消息在底部
            List<ChatMessage> sortedMessages = messages.stream()
                    .sorted((m1, m2) -> m1.getTimestamp().compareTo(m2.getTimestamp()))
                    .collect(Collectors.toList());

            log.info("获取聊天记录: {} <-> {}, 会话ID: {}, 数量: {}, 页码: {}, 大小: {}",
                user1, user2, conversationId, sortedMessages.size(), page, size);
            return sortedMessages;

        } catch (Exception e) {
            log.error("获取聊天记录失败: {} <-> {}", user1, user2, e);
            throw new RuntimeException("获取聊天记录失败: " + e.getMessage(), e);
        }
    }

    /**
     * 通过用户ID获取两个用户之间的聊天记录
     */
    public List<ChatMessage> getChatHistoryByIds(Integer user1Id, Integer user2Id, int page, int size) {
        try {
            if (user1Id == null || user2Id == null) {
                throw new IllegalArgumentException("用户ID不能为空");
            }

            Query query = new Query();

            // 查询两个用户之间的消息（双向）
            Criteria criteria = new Criteria().orOperator(
                    Criteria.where("fromId").is(user1Id).and("toId").is(user2Id),
                    Criteria.where("fromId").is(user2Id).and("toId").is(user1Id)
            ).and("isDeleted").is(false);

            query.addCriteria(criteria);

            // 按时间倒序排列
            query.with(Sort.by(Sort.Direction.DESC, "timestamp"));

            // 分页
            if (page >= 0 && size > 0) {
                Pageable pageable = PageRequest.of(page, size);
                query.with(pageable);
            }

            List<ChatMessage> messages = mongoTemplate.find(query, ChatMessage.class);

            // 反转列表，使最新消息在底部
            List<ChatMessage> sortedMessages = messages.stream()
                    .sorted((m1, m2) -> m1.getTimestamp().compareTo(m2.getTimestamp()))
                    .collect(Collectors.toList());

            log.info("通过ID获取聊天记录: {} <-> {}, 数量: {}, 页码: {}, 大小: {}",
                user1Id, user2Id, sortedMessages.size(), page, size);
            return sortedMessages;

        } catch (Exception e) {
            log.error("通过ID获取聊天记录失败: {} <-> {}", user1Id, user2Id, e);
            throw new RuntimeException("获取聊天记录失败: " + e.getMessage(), e);
        }
    }

    /**
     * 标记消息为已读（基于用户名）
     */
    public void markMessagesAsRead(String fromUser, String toUser) {
        try {
            Query query = new Query();

            // 查询fromUser发给toUser的未读消息
            Criteria criteria = Criteria.where("fromName").is(fromUser)
                    .and("toName").is(toUser)
                    .and("isRead").is(false)
                    .and("isDeleted").is(false);

            query.addCriteria(criteria);

            Update update = new Update().set("isRead", true);

            long updateCount = mongoTemplate.updateMulti(query, update, ChatMessage.class).getModifiedCount();
            log.debug("标记消息已读: {} -> {}, 数量: {}", fromUser, toUser, updateCount);

        } catch (Exception e) {
            log.error("标记消息已读失败", e);
            throw e;
        }
    }

    /**
     * 标记消息为已读（基于用户ID）
     */
    public void markMessagesAsReadByIds(Integer fromUserId, Integer toUserId) {
        try {
            if (fromUserId == null || toUserId == null) {
                throw new IllegalArgumentException("用户ID不能为空");
            }

            Query query = new Query();

            // 查询fromUserId发给toUserId的未读消息
            Criteria criteria = Criteria.where("fromId").is(fromUserId)
                    .and("toId").is(toUserId)
                    .and("isRead").is(false)
                    .and("isDeleted").is(false);

            query.addCriteria(criteria);

            Update update = new Update().set("isRead", true);

            long updateCount = mongoTemplate.updateMulti(query, update, ChatMessage.class).getModifiedCount();
            log.debug("标记消息已读: {} -> {}, 数量: {}", fromUserId, toUserId, updateCount);

        } catch (Exception e) {
            log.error("标记消息已读失败", e);
            throw e;
        }
    }

    /**
     * 获取未读消息数量（基于用户名）
     */
    public long getUnreadMessageCount(String username) {
        try {
            Query query = new Query();

            Criteria criteria = Criteria.where("toName").is(username)
                    .and("isRead").is(false)
                    .and("isDeleted").is(false);

            query.addCriteria(criteria);

            long count = mongoTemplate.count(query, ChatMessage.class);
            log.debug("用户 {} 的未读消息数量: {}", username, count);
            return count;

        } catch (Exception e) {
            log.error("获取未读消息数量失败", e);
            return 0;
        }
    }

    /**
     * 获取未读消息数量（基于用户ID）
     */
    public long getUnreadMessageCountById(Integer userId) {
        try {
            if (userId == null) {
                throw new IllegalArgumentException("用户ID不能为空");
            }

            Query query = new Query();

            Criteria criteria = Criteria.where("toId").is(userId)
                    .and("isRead").is(false)
                    .and("isDeleted").is(false);

            query.addCriteria(criteria);

            long count = mongoTemplate.count(query, ChatMessage.class);
            log.debug("用户 {} 的未读消息数量: {}", userId, count);
            return count;

        } catch (Exception e) {
            log.error("获取未读消息数量失败", e);
            return 0;
        }
    }

    /**
     * 获取用户的所有对话列表（最新消息）
     */
    public List<ChatMessage> getConversationList(Integer userId) {
        try {
            if (userId == null) {
                throw new IllegalArgumentException("用户ID不能为空");
            }

            System.out.println("获取对话列表查询参数userId:"+userId);
            // 使用聚合查询获取最新的对话记录
            // 这里简化实现，实际项目中可以使用MongoDB的聚合管道
            Query query = new Query();

            Criteria criteria = new Criteria().orOperator(
                Criteria.where("fromId").is(userId),
                Criteria.where("toId").is(userId)
            ).andOperator(
                Criteria.where("isDeleted").is(false)
            );

            query.addCriteria(criteria);
            query.with(Sort.by(Sort.Direction.DESC, "timestamp"));

            List<ChatMessage> messages = mongoTemplate.find(query, ChatMessage.class);
            System.out.println("获取对话列表查询结果:"+messages.toString());
            // 按对话分组，只返回每个对话的最新消息
            Map<String, ChatMessage> conversationMap = messages.stream()
                    .collect(Collectors.toMap(
                        msg -> getConversationKeyById(msg, userId),
                        msg -> msg,
                        (existing, replacement) -> existing.getTimestamp().isAfter(replacement.getTimestamp()) ? existing : replacement
                    ));

            List<ChatMessage> conversations = conversationMap.values().stream()
                    .sorted((m1, m2) -> m2.getTimestamp().compareTo(m1.getTimestamp()))
                    .collect(Collectors.toList());

            for (ChatMessage conversation : conversations) {
                // 添加用户头像和用户昵称
                // 确定目标用户ID（对方用户）
                Integer targetUserId = conversation.getFromId().equals(userId) ? conversation.getToId() : conversation.getFromId();

                // 获取目标用户信息
                User targetUser = userService.getOne(new QueryWrapper<User>().eq("id", Long.valueOf(targetUserId)));
                if (targetUser != null) {
                    // 设置目标用户头像
                    String targetAvatar = null;
                    if (StringUtils.hasText(targetUser.getAvatar()) && !"identity_verified".equals(targetUser.getAvatar())) {
                        targetAvatar = targetUser.getAvatar();
                    }
                    conversation.setTargetAvatar(targetAvatar);

                    // 设置目标用户昵称（优先使用昵称，没有则使用用户名）
                    String targetName = StringUtils.hasText(targetUser.getNickname()) ?
                                       targetUser.getNickname() : targetUser.getUsername();
                    conversation.setTargetName(targetName);

                    log.debug("设置目标用户信息: ID={}, 昵称={}, 头像={}",
                             targetUserId, targetName, targetAvatar != null ? "已设置" : "默认");
                }
            }

            log.debug("获取用户 {} 的对话列表，数量: {}", userId, conversations.size());
            return conversations;

        } catch (Exception e) {
            log.error("获取对话列表失败", e);
            throw e;
        }
    }

    /**
     * 生成对话唯一键（基于用户名）
     */
    private String getConversationKey(ChatMessage message, String currentUser) {
        String otherUser = message.getFromName().equals(currentUser) ? message.getToName() : message.getFromName();
        return otherUser;
    }

    /**
     * 生成对话唯一键（基于用户ID）
     */
    private String getConversationKeyById(ChatMessage message, Integer currentUserId) {
        Integer otherUserId = message.getFromId().equals(currentUserId) ? message.getToId() : message.getFromId();
        return otherUserId.toString();
    }

    /**
     * 清空用户的所有聊天记录（软删除）
     */
    public boolean clearAllUserMessages(String username) {
        try {
            if (username == null || username.trim().isEmpty()) {
                throw new IllegalArgumentException("用户名不能为空");
            }

            username = username.trim();

            Query query = new Query();

            // 查询该用户作为发送者或接收者的所有消息
            Criteria criteria = new Criteria().orOperator(
                Criteria.where("fromName").is(username),
                Criteria.where("toName").is(username)
            ).andOperator(
                Criteria.where("isDeleted").is(false) // 只处理未删除的消息
            );

            query.addCriteria(criteria);

            // 软删除：将isDeleted字段设置为true
            Update update = new Update().set("isDeleted", true);

            long updateCount = mongoTemplate.updateMulti(query, update, ChatMessage.class).getModifiedCount();

            log.info("清空用户 {} 的所有聊天记录，删除数量: {}", username, updateCount);

            return updateCount > 0;

        } catch (Exception e) {
            log.error("清空用户聊天记录失败: {}", username, e);
            throw new RuntimeException("清空聊天记录失败: " + e.getMessage(), e);
        }
    }

    /**
     * 物理删除用户的所有聊天记录（谨慎使用）
     */
    public boolean deleteAllUserMessages(String username) {
        try {
            if (username == null || username.trim().isEmpty()) {
                throw new IllegalArgumentException("用户名不能为空");
            }

            username = username.trim();

            Query query = new Query();

            // 查询该用户作为发送者或接收者的所有消息
            Criteria criteria = new Criteria().orOperator(
                Criteria.where("fromName").is(username),
                Criteria.where("toName").is(username)
            );

            query.addCriteria(criteria);

            // 物理删除
            long deleteCount = mongoTemplate.remove(query, ChatMessage.class).getDeletedCount();

            log.warn("物理删除用户 {} 的所有聊天记录，删除数量: {}", username, deleteCount);

            return deleteCount > 0;

        } catch (Exception e) {
            log.error("物理删除用户聊天记录失败: {}", username, e);
            throw new RuntimeException("删除聊天记录失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取并设置消息中双方的头像信息
     */
    private void setUserAvatars(ChatMessage message) {
        try {
            // 获取发送方头像
            String fromAvatar = getUserAvatar(message.getFromId());
            message.setFromAvatar(fromAvatar);

            // 获取接收方头像
            String toAvatar = getUserAvatar(message.getToId());
            message.setToAvatar(toAvatar);

            log.debug("设置头像信息: {} -> {}, 发送方头像: {}, 接收方头像: {}",
                message.getFromName(), message.getToName(),
                fromAvatar != null ? "已设置" : "默认",
                toAvatar != null ? "已设置" : "默认");

        } catch (Exception e) {
            log.warn("获取用户头像失败: {}", e.getMessage());
            // 头像获取失败不影响消息保存，使用默认头像
        }
    }

    /**
     * 根据用户名获取用户头像
     */
    private String getUserAvatar(Integer id) {
        try {
            if (id == null) {
                return null;
            }

            User user = userService.getOne(new QueryWrapper<User>()
                    .eq("id", Long.valueOf(id))
                    .eq("status", 1)); // 只查询正常状态的用户

            if (user != null && StringUtils.hasText(user.getAvatar())
                && !"identity_verified".equals(user.getAvatar())) {
                return user.getAvatar();
            }

            return null;
        } catch (Exception e) {
            log.warn("查询用户 {} 头像失败: {}", id, e.getMessage());
            return null;
        }
    }

    /**
     * 根据关键词搜索聊天记录
     * @param keyword 搜索关键词
     * @param userId 当前用户ID
     * @param username 当前用户名
     * @return 匹配的聊天记录列表
     */
    public List<ChatMessage> searchMessagesByKeyword(String keyword, Integer userId, String username) {
        try {
            if (keyword == null || keyword.trim().isEmpty()) {
                return new ArrayList<>();
            }

            keyword = keyword.trim();
            Query query = new Query();

            // 构建搜索条件：消息内容包含关键词，且当前用户参与了对话
            Criteria criteria = new Criteria();

            if (userId != null) {
                // 使用用户ID搜索
                criteria = new Criteria().orOperator(
                    Criteria.where("fromId").is(userId),
                    Criteria.where("toId").is(userId)
                ).and("message").regex(keyword, "i") // 不区分大小写的正则匹配
                .and("isDeleted").is(false);
            } else if (username != null && !username.trim().isEmpty()) {
                // 使用用户名搜索
                criteria = new Criteria().orOperator(
                    Criteria.where("fromName").is(username.trim()),
                    Criteria.where("toName").is(username.trim())
                ).and("message").regex(keyword, "i") // 不区分大小写的正则匹配
                .and("isDeleted").is(false);
            } else {
                log.warn("搜索聊天记录时缺少用户标识");
                return new ArrayList<>();
            }

            query.addCriteria(criteria);

            // 按时间倒序排列，限制结果数量
            query.with(Sort.by(Sort.Direction.DESC, "timestamp"));
            query.limit(50); // 限制最多返回50条记录

            List<ChatMessage> messages = mongoTemplate.find(query, ChatMessage.class);

            // 填充头像信息
//            for (ChatMessage message : messages) {
////                fillAvatarInfo(message);
//            }

            log.info("搜索聊天记录: 关键词={}, 用户ID={}, 用户名={}, 结果数量={}",
                keyword, userId, username, messages.size());

            return messages;

        } catch (Exception e) {
            log.error("搜索聊天记录失败: 关键词={}, 用户ID={}, 用户名={}", keyword, userId, username, e);
            return new ArrayList<>();
        }
    }
}